package com.uam.core.entity.uitls;

import com.uam.core.entity.constant.CommonConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description 时间处理类
 * @Author heguanglong
 * @Date 2018/11/5 16:01
 * @Modify
 */
public interface DateUtils {
    Logger log = LoggerFactory.getLogger(DateUtils.class);

    static ThreadLocal<Map<String, SimpleDateFormat>> THREAD_LOCAL = new ThreadLocal<Map<String, SimpleDateFormat>>() {
        @Override
        protected Map<String, SimpleDateFormat> initialValue() {
            return new HashMap<String, SimpleDateFormat>(CommonConstant.SIXTEEN);
        }
    };

    /**
     * todo
     *
     * @param pattern
     * @return
     */
    static SimpleDateFormat getSimpleDateFormat(final String pattern) {
        Map<String, SimpleDateFormat> simpleDateFormatMap = THREAD_LOCAL.get();
        SimpleDateFormat format = simpleDateFormatMap.get(pattern);
        if (format == null) {
            format = new SimpleDateFormat(pattern);
            simpleDateFormatMap.put(pattern, format);
        }
        return format;
    }

    /**
     * todo
     *
     * @param dateStr
     * @param pattern
     * @return java.util.Date
     * @throws ParseException
     * @description string to date
     * @author heguanglong
     * @date 2019-03-21 16:40
     **/
    static Date parse(String dateStr, String pattern) throws ParseException {
        return getSimpleDateFormat(pattern).parse(dateStr);
    }

    /**
     * todo
     *
     * @param dateStr
     * @return java.util.Date
     * @throws ParseException
     * @description string to date
     * @author heguanglong
     * @date 2019-03-21 16:40
     **/
    static Date parse(String dateStr) throws ParseException {
        if (StringUtils.isEmpty(dateStr)) {
            return null;
        }
        String pattern = "yyMMddHHmmss";
        return getSimpleDateFormat(pattern).parse(dateStr);
    }


    /**
     * todo
     *
     * @param date
     * @return java.lang.String
     * @description date to String
     * @author heguanglong
     * @date 2019-03-21 16:41
     **/
    static String format(Date date) {
        if (date == null) {
            return null;
        }
        String pattern = "yyyy-MM-dd HH:mm:ss";
        return getSimpleDateFormat(pattern).format(date);
    }

    /**
     * 时间转换 str-date
     *
     * @param date
     * @param pattern
     * @return java.util.Date
     * @throws ParseException
     * @author heguanglong
     * @date 2019-11-20 15:13
     **/
    static Date parseDate(String date, String pattern) throws ParseException {
        if (date == null || StringUtils.isEmpty(pattern)) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.parse(date);
    }

    /**
     * 获取日期年份
     *
     * @param date 日期
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static int getYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 功能描述：返回月
     *
     * @param date Date 日期
     * @return 返回月份
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static int getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 功能描述：返回日
     *
     * @param date Date 日期
     * @return 返回日份
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 功能描述：返回小
     *
     * @param date 日期
     * @return 返回小时
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static int getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 功能描述：返回分
     *
     * @param date 日期
     * @return 返回分钟
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static int getMinute(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 返回秒钟
     *
     * @param date Date 日期
     * @return 返回秒钟
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static int getSecond(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }

    /**
     * 功能描述：返回毫
     *
     * @param date 日期
     * @return 返回毫
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static long getMillis(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当前日期
     *
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static String getCurrentDate() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 获取当前日期 yyyy-MM-dd HH:mm
     *
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static String getCurrentDateHhMm() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 获取昨天日期
     *
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static String getYesterdayDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        String yesterday = new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
        return yesterday;
    }

    /**
     * 获取date的count天之前或者之后的开始时间
     *
     * @param date     日志
     * @param countDay 隔的天数
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static long getDayStartTime(Date date, int countDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, countDay);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime().getTime();
    }

    /**
     * 获取最近12个月的开始时间和结束时间
     *
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static Map<String, String> getNear12MonthAllTime() {
        Map<String, String> result = new LinkedHashMap<>(CommonConstant.SIXTEEN);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String start = " 00:00:00";
        Calendar calendar0 = Calendar.getInstance();
        calendar0.set(Calendar.DAY_OF_MONTH, 1);
        calendar0.add(Calendar.MONTH, 1);
        for (int i = 0; i < CommonConstant.TWELVE; i++) {
            String endTime = sdf.format(calendar0.getTime()) + start;
            calendar0.add(Calendar.MONTH, -1);
            String startTime = sdf.format(calendar0.getTime()) + start;
            result.put(startTime, endTime);
        }
        return result;
    }

    /**
     * 获取最近12个月的时间，倒序排序
     *
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static List<String> getNear12MothSimpleTime() {
        List<String> list = new ArrayList<>(20);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar calendar0 = Calendar.getInstance();
        calendar0.add(Calendar.MONTH, -11);
        list.add(sdf.format(calendar0.getTime()));
        for (int i = 0; i < CommonConstant.ELEVEN; i++) {
            calendar0.add(Calendar.MONTH, 1);
            list.add(sdf.format(calendar0.getTime()));
        }
        return list;
    }

    /**
     * 计算指定年月的周数
     *
     * @param date
     * @return int
     * @throws ParseException
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static int getMaxWeekNum(String date) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date s = sdf.parse(date);
        Calendar ca = Calendar.getInstance();
        ca.setTime(s);
        ca.setFirstDayOfWeek(Calendar.MONDAY);
        return ca.getActualMaximum(Calendar.WEEK_OF_MONTH);
    }

    /**
     * 获取最近12个月的时间，倒序排序
     *
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static String getNear12MothString() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        return sdf.format(new Date());
    }

    /**
     * 日期格式化
     *
     * @param dateString
     * @return
     * @throws ParseException
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static String dateParse(String dateString) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date temp = sdf.parse(dateString);
        return new SimpleDateFormat("yyyyMM").format(temp);
    }

    /**
     * 时间格式化
     *
     * @param timeString
     * @return
     * @throws ParseException
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static String timeParse(String timeString) {
        SimpleDateFormat sdf = new SimpleDateFormat("HH");
        Date temp = null;
        try {
            temp = sdf.parse(timeString);
        } catch (ParseException e) {
            log.error("timeParse", e);
        }
        return new SimpleDateFormat("HH:mm").format(temp);
    }

    /**
     * 获取每5分钟时间列表
     *
     * @param endTime
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static List<String> minutesList(Date endTime) {
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
        Calendar cStart = Calendar.getInstance();
        cStart.set(Calendar.HOUR_OF_DAY, 0);
        cStart.set(Calendar.MINUTE, 0);
        cStart.set(Calendar.SECOND, 0);
        Calendar cEnd = Calendar.getInstance();
        if (null == endTime) {
            cEnd.set(Calendar.HOUR_OF_DAY, 23);
            cEnd.set(Calendar.MINUTE, 55);
            cEnd.set(Calendar.SECOND, 0);
        } else {
            cEnd.setTime(new Date());
        }
        List dateList = new ArrayList();
        dateList.add(format.format(cStart.getTime()));
        while (cEnd.getTime().after(cStart.getTime())) {
            cStart.add(Calendar.MINUTE, 5);
            dateList.add(format.format(cStart.getTime()));
        }
        return dateList;
    }

    /**
     * 获取当前小时
     *
     * @return
     * @date 2019/10/11 19:55
     * @modify heguanglong
     */
    static int getCurrentHour() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("HH");
        String hourString = formatter.format(currentTime);
        return Integer.parseInt(hourString);
    }


    /**
     * 得到两个时间之间的秒，日期格式的 end - start 失败返回 -1
     *
     * @param startDate
     * @param endDate
     * @return
     */
    static int getSecondsBetween2Date(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            log.error("开始时间或结束时间不能为空");
            return -1;
        }
        int seconds = Long.valueOf((endDate.getTime() - startDate.getTime()) / 1000).intValue();
        return seconds;
    }


    /**
     * 得到两个时间之间的分钟，日期格式的 end - start 失败返回 -1
     *
     * @param startDate
     * @param endDate
     * @return
     */
    static long getMinutesBetween2Date(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            log.error("开始时间或结束时间不能为空");
            return -1;
        }
        return Long.valueOf((endDate.getTime() - startDate.getTime()) / 60000).longValue();
    }

    /**
     * todo
     *
     * @param startDate
     * @param endDate
     * @return
     */
    static long getMinutesBetween2DateInterval(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            log.error("开始时间或结束时间不能为空");
            return -1;
        }
        Long sTime = startDate.getTime();
        Long eTime = endDate.getTime();
        if (sTime <= eTime) {
            endDate = new Date();
        }
        return Long.valueOf((endDate.getTime() - startDate.getTime()) / 60000).longValue();
    }

    /**
     * todo
     *
     * @param date
     * @param minute
     * @return
     */
    static Date addMinutes(Date date, int minute) {
        if (date == null) {
            log.error("日期对象不能为空");
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minute);
        return c.getTime();
    }

    /**
     * todo
     *
     * @param date
     * @param pattern
     * @return
     * @throws ParseException
     * @author heguanglong
     * @describe 时间转换 date-->str
     * @createDate 2020年3月8日
     */
    static String parseDateToStr(Date date, String pattern) throws ParseException {
        if (date == null || StringUtils.isEmpty(pattern)) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(date);
    }


    /**
     * todo
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return
     * @author heguanglong
     * @describe 获取两个时间的相差的分钟秒
     * @createDate 2020年3月9日
     */
    static String formatTime(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            log.error("开始时间和结束时间不能为空");
            return null;
        }
        long millis = endDate.getTime() - startDate.getTime();
        long minutes = millis / 1000 / 60;
        long seconds = (millis / 1000) % 60;
        StringBuilder sBuilder = new StringBuilder();
        sBuilder.append(minutes).append("分").append(seconds).append("秒");
        return sBuilder.toString();
    }

    /**
     * todo
     *
     * @param startDate
     * @param endDate
     * @param type
     * @return
     */
    static long formatTime(Date startDate, Date endDate, int type) {
        long interval = (endDate.getTime() - startDate.getTime()) / 1000;
        if (Calendar.HOUR == type) {
            return interval / 3600;
        } else if (Calendar.MINUTE == type) {
            return interval % 3600 / 60;
        } else if (Calendar.SECOND == type) {
            return interval % 60;
        } else {
            throw new IllegalArgumentException("不支持的参数type");
        }
    }

    /**
     * 判断时间是否在时间段内
     *
     * @param nowTime
     * @param beginTime
     * @param endTime
     * @return
     */
    public static boolean belongCalendar(Date nowTime, Date beginTime,
                                         Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断时间是否在时间段内
     *
     * @param nowTime      当前时间 HH:mm
     * @param beginTimeStr 开始时间 HH:mm
     * @param endTimeStr   结束时间 HH:mm
     * @return
     * @throws Exception
     */
    public static boolean belongCalendar(Date nowTime, String beginTimeStr,
                                         String endTimeStr) throws Exception {
        if (nowTime == null) {
            nowTime = new Date();
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String bigStr = sdf.format(nowTime) + " " + beginTimeStr;
        String endStr = sdf.format(nowTime) + " " + endTimeStr;
        Date beginTime = DateUtils.parse(bigStr, "yyyy-MM-dd HH:mm");
        Date endTime = DateUtils.parse(endStr, "yyyy-MM-dd HH:mm");

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        boolean flag;
        if (date.after(begin) && date.before(end)) {
            flag = true;
        } else {
            flag = false;
        }
        return flag;
    }

    /**
     * 返回当前时间的毫秒级别的
     *
     * @return
     * @date 2021-03-26
     * @modify heguanglong
     */
    static Long getNewDateSs() {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        synchronized (format) {
            return Long.valueOf(format.format(new Date()));
        }
    }

    /**
     * todo
     *
     * @param date
     * @return java.util.Date
     * @throws ParseException
     * @description string to date
     * @author heguanglong
     * @date 2019-03-21 16:40
     **/
    static   String  parseStr(Date date) throws ParseException {
        String pattern = "yyMMddHHmmss";
        return getSimpleDateFormat(pattern).format(date);
    }
}
